options(max.print=1000000)
Warning message:
R graphics engine version 14 is not supported by this version of RStudio. The Plots tab will be disabled until a newer version of RStudio is installed.
library(readxl)
library(dplyr)
Attaching package: 㤼㸱dplyr㤼㸲
The following objects are masked from 㤼㸱package:stats㤼㸲:
filter, lag
The following objects are masked from 㤼㸱package:base㤼㸲:
intersect, setdiff, setequal, union
fileName <- "ANZ synthesised transaction dataset.xlsx"
df <- as.data.frame(read_xlsx(fileName))
Expecting numeric in C3052 / R3052C3: got 'THE DISCOUNT CHEMIST GROUP'Expecting numeric in C4360 / R4360C3: got 'LAND WATER & PLANNING East Melbourne'
# df %>% rmarkdown::paged_table()
# for (i in seq_along(1:ncol(df)))
# {
# print(paste("Column ", i, " = ", sum(is.na(df[i]))))
# }
summary(df$amount)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.10 16.00 29.00 187.93 53.66 8835.98
df
#print(df[, 'amount'])
### Average Transaction amount ###
avg_transaction <- mean(df$amount)
{
plot(avg_transaction, ylab="Average Transaction")
abline(h=avg_transaction, col='blue')
legend("topright", legend=paste("Mean: ", round(avg_transaction, digits=2)),
col="blue", lty=1:2, cex=0.8)
title(expression(phantom("title (") * "Average Transaction Amount"), col.main = "purple")
}


library(ggdemetra)
#### Finding and pointing Outliers #####
{
png(filename="outliers.png", width=1350, height=600)
### Labels
l1 <- labs(x="Names", y="Average Value", title="Outliers", colour='Outliers', size=14)
### Theme Start
t<- theme(legend.position = c(.98, .98), legend.justification = c("right", "top"),axis.text=element_text(size=12), axis.title=element_text(size=14,face="bold"),
legend.title=element_text(colour='red', size=19), axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1, size=12))
### Geom_Point
gp <- geom_point(col='blue', size=4)
### Geom_Text
gt <- geom_text(aes(label= ifelse(mean_amount_by_names[, 'x'] > quantile(mean_amount_by_names[, 'x'], 0.97) | mean_amount_by_names[, 'x'] < quantile(mean_amount_by_names[, 'x'], 0.01),
as.character(mean_amount_by_names[, 'Group.1']),'')),hjust=0,vjust=1,size=6,show.legend =T)
### Lapply, ggplot
list_plots <- lapply(mean_amount_by_names[-1], function(data)
ggplot(mean_amount_by_names, aes(x= Group.1, y = x, colour='orange', label=mean_amount_by_names[, 'Group.1'])) + t + l1 + gp + gt)
print(list_plots[[1]])
dev.off()
}
null device
1
library(lubridate)
Attaching package: 㤼㸱lubridate㤼㸲
The following objects are masked from 㤼㸱package:base㤼㸲:
date, intersect, setdiff, union
library(dplyr)
library(collapsibleTree)
Registered S3 methods overwritten by 'htmltools':
method from
print.html tools:rstudio
print.shiny.tag tools:rstudio
print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'htmlwidgets':
method from
print.htmlwidget tools:rstudio
# df %>%
# mutate(months = month(as.POSIXlt(month_extract, format="%d-%m-%Y"))) -> df
# arrange_by_month <- arrange(df, df$months)
# fa <- factor(df$months)
# fa <- factor(fa, levels=c(8, 9, 10))
amount_account_data <- c()
# x<-arrange(df, df$first_name)
#new_data$'Name' <- append(new_data, factor(x$first_name))
account_fact <- factor(x$account)
p <- aggregate(df$amount, list(account_fact), sum)
customer_id_fact <- factor(x$customer_id)
amount_account_data <- append(amount_account_data, p)
z <- c()
for (o in levels(customer_id_fact)){
z <- append(z, o) #z
}
z <- bind_rows(as.data.frame(z))
amount_account_data <- append(amount_account_data, z)
library(webshot)
z1 <- c()
namesA <- c()
x <- data.frame(x)
for (k in seq_along(1:100)){
namesA <- filter(x, x$account == amount_account_data$Group.1[k])
z1 <- append(z1, namesA$first_name[1])
}
z1 <- bind_rows(as.data.frame(z1))
amount_account_data <- append(amount_account_data, z1)
amount_account_data
$Group.1
[1] ACC-1037050564 ACC-1056639002 ACC-1199531521 ACC-1217063613 ACC-1222300524
[6] ACC-1243371644 ACC-1279356312 ACC-1334819143 ACC-1344825761 ACC-1349834573
[11] ACC-1424176027 ACC-1438600314 ACC-1443681913 ACC-1496451953 ACC-1516130869
[16] ACC-1523339231 ACC-154431271 ACC-1598451071 ACC-1608363396 ACC-1650504218
[21] ACC-1652235822 ACC-1683215619 ACC-1710017148 ACC-1788473090 ACC-1799207998
[26] ACC-182446574 ACC-1890605467 ACC-1903037542 ACC-1973887809 ACC-1990648130
[31] ACC-1998563091 ACC-2014856841 ACC-2107684084 ACC-211792489 ACC-2153562714
[36] ACC-2171593283 ACC-2173390920 ACC-2231965366 ACC-2249586092 ACC-2259139624
[41] ACC-2265520058 ACC-2270192619 ACC-2305712452 ACC-240804743 ACC-2528867619
[46] ACC-2615038700 ACC-2650850707 ACC-2673069055 ACC-2674800293 ACC-2681137560
[51] ACC-2776252858 ACC-2828321672 ACC-2890243754 ACC-2897221629 ACC-2901672282
[56] ACC-2920611728 ACC-2970114956 ACC-2988263882 ACC-3021093232 ACC-3084464802
[61] ACC-3100725361 ACC-3233697971 ACC-3317636250 ACC-3326339947 ACC-3481401842
[66] ACC-3485804958 ACC-3536132544 ACC-354106658 ACC-3541460373 ACC-3689607373
[71] ACC-3741880913 ACC-37709441 ACC-3771436525 ACC-3827517394 ACC-3879258709
[76] ACC-3881031190 ACC-38923874 ACC-3941181087 ACC-3954677887 ACC-4059612845
[81] ACC-4065652575 ACC-414431115 ACC-4163822186 ACC-4258502723 ACC-4274272854
[86] ACC-4281711154 ACC-53508546 ACC-559365433 ACC-574997646 ACC-588564840
[91] ACC-602667573 ACC-721712940 ACC-80388494 ACC-819621312 ACC-847145727
[96] ACC-854938045 ACC-90814749 ACC-958000567 ACC-964839203 ACC-966140392
100 Levels: ACC-1037050564 ACC-1056639002 ACC-1199531521 ... ACC-966140392
$x
[1] 12150.43 15875.79 35063.36 5840.75 79965.86 23832.75 22324.65 19910.80
[9] 46827.01 9404.75 8556.48 15898.37 24112.65 21313.13 31584.38 18226.79
[17] 36117.30 100432.78 29282.43 21740.33 36853.95 5066.66 38064.37 8997.66
[25] 37250.92 54482.29 5625.67 32829.25 34061.22 5007.11 10111.99 8964.33
[33] 19825.51 17455.83 5380.52 3559.81 23780.66 7849.89 47811.20 1795.14
[41] 32162.84 7887.33 24154.79 27828.28 28650.46 1862.70 9047.48 61419.41
[49] 1465.10 17468.17 7465.84 3236.67 46552.40 3592.86 23939.05 20471.49
[57] 15824.50 10051.78 3113.29 24373.77 21246.25 7220.04 10203.67 1904.56
[65] 53327.42 60978.15 21791.81 28154.84 12145.80 43030.76 2868.64 24083.42
[73] 40490.46 26766.77 34607.58 3978.69 18146.62 17651.01 43153.30 11590.34
[81] 32875.26 18937.73 31828.85 68420.97 4525.39 2047.24 14308.00 12229.55
[89] 23970.88 21660.70 19307.04 5206.28 19594.42 8039.26 20102.11 24830.64
[97] 17530.25 36750.22 17543.92 26432.38
$z
[1] "CUS-1005756958" "CUS-1117979751" "CUS-1140341822" "CUS-1147642491"
[5] "CUS-1196156254" "CUS-1220154422" "CUS-1233833708" "CUS-1271030853"
[9] "CUS-127297539" "CUS-134193016" "CUS-134833760" "CUS-1388323263"
[13] "CUS-1433879684" "CUS-1462656821" "CUS-1478398256" "CUS-1499065773"
[17] "CUS-1604596597" "CUS-1609060617" "CUS-1614226872" "CUS-1617121891"
[21] "CUS-164374203" "CUS-1646183815" "CUS-1646621553" "CUS-1654129794"
[25] "CUS-1669695324" "CUS-1739931018" "CUS-1790886359" "CUS-1816693151"
[29] "CUS-1842679196" "CUS-1892177589" "CUS-1896554896" "CUS-1928710999"
[33] "CUS-2031327464" "CUS-2059096722" "CUS-2083971310" "CUS-2110742437"
[37] "CUS-2142601169" "CUS-2155701614" "CUS-2178051368" "CUS-2206365095"
[41] "CUS-2283904812" "CUS-2317998716" "CUS-2348881191" "CUS-2370108457"
[45] "CUS-2376382098" "CUS-2484453271" "CUS-2487424745" "CUS-2500783281"
[49] "CUS-2505971401" "CUS-2599279756" "CUS-261674136" "CUS-2630892467"
[53] "CUS-2650223890" "CUS-2663907001" "CUS-2688605418" "CUS-2695611575"
[57] "CUS-2738291516" "CUS-2819545904" "CUS-2977593493" "CUS-3026014945"
[61] "CUS-3117610635" "CUS-3129499595" "CUS-3142625864" "CUS-3151318058"
[65] "CUS-3174332735" "CUS-3180318393" "CUS-3201519139" "CUS-3249305314"
[69] "CUS-325142416" "CUS-3255104878" "CUS-326006476" "CUS-331942311"
[73] "CUS-3325710106" "CUS-3336454548" "CUS-3378712515" "CUS-3395687666"
[77] "CUS-3431016847" "CUS-3462882033" "CUS-3702001629" "CUS-3716701010"
[81] "CUS-3904958894" "CUS-3989008654" "CUS-4023861240" "CUS-4123612273"
[85] "CUS-4142663097" "CUS-423725039" "CUS-443776336" "CUS-495599312"
[89] "CUS-497688347" "CUS-511326734" "CUS-51506836" "CUS-527400765"
[93] "CUS-537508723" "CUS-55310383" "CUS-586638664" "CUS-72755508"
[97] "CUS-809013380" "CUS-860700529" "CUS-880898248" "CUS-883482547"
$z1
[1] "Rhonda" "Michael" "Billy" "Kimberly" "Michael"
[6] "Gregory" "Tyler" "Christopher" "Sarah" "Matthew"
[11] "Donald" "Maria" "Ryan" "Ricky" "Jessica"
[16] "Tim" "Lori" "Diana" "Robert" "Marissa"
[21] "Renee" "Barry" "Michelle" "Rachael" "Susan"
[26] "Tonya" "Alexander" "Jeffrey" "Antonio" "Kaitlyn"
[31] "David" "Patrick" "Richard" "Jacqueline" "Linda"
[36] "Fernando" "Luis" "Linda" "Edward" "Cindy"
[41] "Catherine" "Darren" "Debra" "Kenneth" "Abigail"
[46] "Emily" "Brian" "Richard" "Elizabeth" "Nathaniel"
[51] "Kristin" "Stephanie" "Joseph" "Scott" "Daniel"
[56] "Tyler" "Robert" "Michael" "Melissa" "Susan"
[61] "Ronald" "Robin" "Kenneth" "Eric" "Tiffany"
[66] "Jessica" "Heather" "Christine" "Jeffrey" "Virginia"
[71] "Ashley" "Charles" "Derek" "Craig" "Natasha"
[76] "Richard" "Ryan" "Paul" "Ruth" "Jonathan"
[81] "Lucas" "Amy" "Karen" "Kimberly" "Timothy"
[86] "Eric" "Kimberly" "Mary" "Mackenzie" "Isaiah"
[91] "Michael" "Andrew" "Dustin" "Michele" "Michael"
[96] "James" "Christopher" "Sandra" "Michael" "Joseph"
amount_account_data <- as.data.frame(amount_account_data)
widgetToPng <- function(widget, file = "widget.png", ...) {
temp <- tempfile(fileext = ".html")
file <- R.utils::getAbsolutePath(file)
htmlwidgets::saveWidget(widget, temp)
webshot(
temp, file,
selector = "#htmlwidget_container",
zoom = 2,
delay = 0.5,
...
)
}
widgetToPng(
collapsibleTreeSummary(
amount_account_data,
hierarchy = c("z1", "Group.1", "z", 'x'),
width = 1000,
height=1000,
fill="lightsteelblue",
root = "Customer Details",
zoomable = FALSE
),
"CustomerDetailsTree.png"
)
Error in collapsibleTreeSummary(amount_account_data, hierarchy = c("z1", :
fill must be a function
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCmBgYHtyfQ0Kb3B0aW9ucyhtYXgucHJpbnQ9MTAwMDAwMCkNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShkcGx5cikNCmZpbGVOYW1lIDwtICJBTlogc3ludGhlc2lzZWQgdHJhbnNhY3Rpb24gZGF0YXNldC54bHN4Ig0KZGYgPC0gYXMuZGF0YS5mcmFtZShyZWFkX3hsc3goZmlsZU5hbWUpKQ0KDQojIGRmICU+JSAgcm1hcmtkb3duOjpwYWdlZF90YWJsZSgpDQoNCiMgZm9yIChpIGluIHNlcV9hbG9uZygxOm5jb2woZGYpKSkNCiMgew0KIyAgIHByaW50KHBhc3RlKCJDb2x1bW4gIiwgaSwgIiA9ICIsIHN1bShpcy5uYShkZltpXSkpKSkNCiMgfQ0Kc3VtbWFyeShkZiRhbW91bnQpDQpkZg0KI3ByaW50KGRmWywgJ2Ftb3VudCddKQ0KDQpgYGANCmBgYHtyfQ0KDQojIyMgQXZlcmFnZSBUcmFuc2FjdGlvbiBhbW91bnQgIyMjDQphdmdfdHJhbnNhY3Rpb24gPC0gbWVhbihkZiRhbW91bnQpDQoNCnsNCiAgcGxvdChhdmdfdHJhbnNhY3Rpb24sIHlsYWI9IkF2ZXJhZ2UgVHJhbnNhY3Rpb24iKQ0KICBhYmxpbmUoaD1hdmdfdHJhbnNhY3Rpb24sIGNvbD0nYmx1ZScpDQogIGxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQ9cGFzdGUoIk1lYW46ICIsIHJvdW5kKGF2Z190cmFuc2FjdGlvbiwgZGlnaXRzPTIpKSwNCiAgICAgICBjb2w9ImJsdWUiLCBsdHk9MToyLCBjZXg9MC44KQ0KICB0aXRsZShleHByZXNzaW9uKHBoYW50b20oInRpdGxlICgiKSAqICJBdmVyYWdlIFRyYW5zYWN0aW9uIEFtb3VudCIpLCBjb2wubWFpbiA9ICJwdXJwbGUiKQ0KfQ0KYGBgDQpgYGB7cn0NCg0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmRmJGRhdGUgPC0gYXMuRGF0ZShkZiRkYXRlKQ0Kd2Vla192YXIgPC0gc3RyZnRpbWUoZGYkZGF0ZSwgZm9ybWF0ID0gIiVWIikNCndlZWtfdmFyIDwtIGZhY3Rvcih3ZWVrX3ZhcikNCmFtb3VudF9zcGVudF93ZWVrbHkgPC0gYWdncmVnYXRlKGRmJGFtb3VudCwgbGlzdCh3ZWVrX3ZhciksIHN1bSkNCndlZWtfbnVtYmVycyA8LSBjKCkNCndlZWtfc3RhcnQgPC0gYXMubnVtZXJpYyhhbW91bnRfc3BlbnRfd2Vla2x5JEdyb3VwLjFbMV0pDQp3ZWVrX2VuZCA8LSBsZW5ndGgoYW1vdW50X3NwZW50X3dlZWtseSRHcm91cC4xKQ0KZm9yIChpIGluIHNlcV9hbG9uZyh3ZWVrX3N0YXJ0OndlZWtfZW5kKSl7DQogIHdlZWtfbnVtYmVycyA8LSBhcHBlbmQod2Vla19udW1iZXJzLCBpKzEgLSB3ZWVrX3N0YXJ0KQ0KfQ0KDQp7DQogIHBuZyhmaWxlbmFtZT0id2Vla2x5X2Ftb3VudC5wbmciLCB3aWR0aD0xMzUwLCBoZWlnaHQ9NjAwKQ0KICANCiAgIyMjIGdncGxvdCBpbml0DQogIA0KICBwbHQgPC0gZ2dwbG90KGFtb3VudF9zcGVudF93ZWVrbHksIGFlcyh3ZWVrX251bWJlcnMsIHgsIGdyb3VwPTEpKQ0KICANCiAgIyMjIExhYmVscw0KICANCiAgbCA8LSBsYWJzKHg9IldlZWsiLCB5PSJBbW91bnQiLCB0aXRsZT0iQW1vdW50IGJ5IHdlZWsiKQ0KICANCiAgIyMjIHRoZW1lIHN0YXJ0DQogIA0KICB0PC0gdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUsIGhqdXN0PTEsIHNpemU9MTIsIGZhY2U9ImJvbGQiLCBjb2xvdXIgPSAiYmx1ZSIpLCANCiAgICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNiwgZmFjZT0gImJvbGQiLCBjb2xvdXI9ICJicm93biIgKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZT0xNCwgZmFjZT0iYm9sZCIsIGNvbG91ciA9ICJvcmFuZ2UiKSwgICAgDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemU9MTQsIGZhY2U9ImJvbGQiLCBjb2xvdXIgPSAib3JhbmdlIiksICAgIA0KICAgICNheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTEyLCBmYWNlPSJib2xkIiwgY29sb3VyID0gImJsYWNrIiksIA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9MTIsIGZhY2U9ImJvbGQiLCBjb2xvdXIgPSAiYmx1ZSIpKSANCiAgDQogICMjI3RoZW1lIGVuZA0KICANCiAgcHJpbnQocGx0K2dlb21fcG9pbnQoc2l6ZT02LCBjb2w9InJlZCIpK2dlb21fbGluZShjb2xvcj0iYmx1ZSIsIHNpemU9MSkrbCt0ICsgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMSwgMTQsIDEpKSkNCiAgZGV2Lm9mZigpDQp9DQogIHByaW50KHBsdCtnZW9tX3BvaW50KHNpemU9NiwgY29sPSJyZWQiKStnZW9tX2xpbmUoY29sb3I9ImJsdWUiLCBzaXplPTEpK2wrdCArIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDEsIDE0LCAxKSkpDQoNCg0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShnZ2RlbWV0cmEpDQojIyMjIEZpbmRpbmcgYW5kIHBvaW50aW5nIE91dGxpZXJzICMjIyMjDQp7DQogIHBuZyhmaWxlbmFtZT0ib3V0bGllcnMucG5nIiwgd2lkdGg9MTM1MCwgaGVpZ2h0PTYwMCkNCiAgDQogICMjIyBMYWJlbHMNCiAgDQogIGwxIDwtIGxhYnMoeD0iTmFtZXMiLCB5PSJBdmVyYWdlIFZhbHVlIiwgdGl0bGU9Ik91dGxpZXJzIiwgY29sb3VyPSdPdXRsaWVycycsIHNpemU9MTQpDQogIA0KICAjIyMgVGhlbWUgU3RhcnQNCiAgICAgIA0KICB0PC0gdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gYyguOTgsIC45OCksIGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygicmlnaHQiLCAidG9wIiksYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTEyKSwgYXhpcy50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0xNCxmYWNlPSJib2xkIiksIA0KICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG91cj0ncmVkJywgc2l6ZT0xOSksIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdD0xLCBzaXplPTEyKSkNCiAgDQogICMjIyBHZW9tX1BvaW50DQogIGdwIDwtIGdlb21fcG9pbnQoY29sPSdibHVlJywgc2l6ZT00KQ0KICANCiAgIyMjIEdlb21fVGV4dA0KICBndCA8LSBnZW9tX3RleHQoYWVzKGxhYmVsPSBpZmVsc2UobWVhbl9hbW91bnRfYnlfbmFtZXNbLCAneCddID4gcXVhbnRpbGUobWVhbl9hbW91bnRfYnlfbmFtZXNbLCAneCddLCAwLjk3KSB8IG1lYW5fYW1vdW50X2J5X25hbWVzWywgJ3gnXSA8IHF1YW50aWxlKG1lYW5fYW1vdW50X2J5X25hbWVzWywgJ3gnXSwgMC4wMSksDQogICAgIGFzLmNoYXJhY3RlcihtZWFuX2Ftb3VudF9ieV9uYW1lc1ssICdHcm91cC4xJ10pLCcnKSksaGp1c3Q9MCx2anVzdD0xLHNpemU9NixzaG93LmxlZ2VuZCA9VCkNCiAgIyMjIExhcHBseSwgZ2dwbG90DQogIGxpc3RfcGxvdHMgPC0gbGFwcGx5KG1lYW5fYW1vdW50X2J5X25hbWVzWy0xXSwgZnVuY3Rpb24oZGF0YSkgDQogICAgIGdncGxvdChtZWFuX2Ftb3VudF9ieV9uYW1lcywgYWVzKHg9IEdyb3VwLjEsIHkgPSB4LCBjb2xvdXI9J29yYW5nZScsIGxhYmVsPW1lYW5fYW1vdW50X2J5X25hbWVzWywgJ0dyb3VwLjEnXSkpICsgdCArIGwxICsgZ3AgKyBndCkNCg0KICBwcmludChsaXN0X3Bsb3RzW1sxXV0pDQogIGRldi5vZmYoKQ0KfQ0KYGBgDQpgYGB7cn0NCmxpYnJhcnkobHVicmlkYXRlKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoY29sbGFwc2libGVUcmVlKQ0KIyBkZiAlPiUgDQojICAgbXV0YXRlKG1vbnRocyA9IG1vbnRoKGFzLlBPU0lYbHQobW9udGhfZXh0cmFjdCwgZm9ybWF0PSIlZC0lbS0lWSIpKSkgLT4gZGYNCg0KIyBhcnJhbmdlX2J5X21vbnRoIDwtIGFycmFuZ2UoZGYsIGRmJG1vbnRocykNCiMgZmEgPC0gZmFjdG9yKGRmJG1vbnRocykNCiMgZmEgPC0gZmFjdG9yKGZhLCBsZXZlbHM9Yyg4LCA5LCAxMCkpDQphbW91bnRfYWNjb3VudF9kYXRhIDwtIGMoKQ0KIyB4PC1hcnJhbmdlKGRmLCBkZiRmaXJzdF9uYW1lKQ0KI25ld19kYXRhJCdOYW1lJyA8LSBhcHBlbmQobmV3X2RhdGEsIGZhY3Rvcih4JGZpcnN0X25hbWUpKQ0KYWNjb3VudF9mYWN0IDwtIGZhY3Rvcih4JGFjY291bnQpDQpwIDwtIGFnZ3JlZ2F0ZShkZiRhbW91bnQsIGxpc3QoYWNjb3VudF9mYWN0KSwgc3VtKQ0KY3VzdG9tZXJfaWRfZmFjdCA8LSBmYWN0b3IoeCRjdXN0b21lcl9pZCkNCmFtb3VudF9hY2NvdW50X2RhdGEgPC0gYXBwZW5kKGFtb3VudF9hY2NvdW50X2RhdGEsIHApDQp6IDwtIGMoKQ0KZm9yIChvIGluIGxldmVscyhjdXN0b21lcl9pZF9mYWN0KSl7DQogIHogPC0gYXBwZW5kKHosIG8pICN6DQp9DQp6IDwtIGJpbmRfcm93cyhhcy5kYXRhLmZyYW1lKHopKQ0KYW1vdW50X2FjY291bnRfZGF0YSA8LSBhcHBlbmQoYW1vdW50X2FjY291bnRfZGF0YSwgeikNCg0KDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KHdlYnNob3QpDQp6MSA8LSBjKCkNCm5hbWVzQSA8LSBjKCkNCnggPC0gZGF0YS5mcmFtZSh4KQ0KZm9yIChrIGluIHNlcV9hbG9uZygxOjEwMCkpew0KICBuYW1lc0EgPC0gZmlsdGVyKHgsIHgkYWNjb3VudCA9PSBhbW91bnRfYWNjb3VudF9kYXRhJEdyb3VwLjFba10pIA0KICB6MSA8LSBhcHBlbmQoejEsIG5hbWVzQSRmaXJzdF9uYW1lWzFdKQ0KfQ0KejEgPC0gYmluZF9yb3dzKGFzLmRhdGEuZnJhbWUoejEpKQ0KYW1vdW50X2FjY291bnRfZGF0YSA8LSBhcHBlbmQoYW1vdW50X2FjY291bnRfZGF0YSwgejEpDQphbW91bnRfYWNjb3VudF9kYXRhDQphbW91bnRfYWNjb3VudF9kYXRhIDwtIGFzLmRhdGEuZnJhbWUoYW1vdW50X2FjY291bnRfZGF0YSkNCg0KIyB3aWRnZXRUb1BuZyA8LSBmdW5jdGlvbih3aWRnZXQsIGZpbGUgPSAid2lkZ2V0LnBuZyIsICAuLi4pIHsNCiMgICB0ZW1wIDwtIHRlbXBmaWxlKGZpbGVleHQgPSAiLmh0bWwiKQ0KIyAgIGZpbGUgPC0gUi51dGlsczo6Z2V0QWJzb2x1dGVQYXRoKGZpbGUpDQojICAgaHRtbHdpZGdldHM6OnNhdmVXaWRnZXQod2lkZ2V0LCB0ZW1wKQ0KIyAgIHdlYnNob3QoDQojICAgICB0ZW1wLCBmaWxlLA0KIyAgICAgc2VsZWN0b3IgPSAiI2h0bWx3aWRnZXRfY29udGFpbmVyIiwNCiMgICAgIHpvb20gPSAyLA0KIyAgICAgZGVsYXkgPSAwLjUsDQojICAgICAuLi4NCiMgICApDQojIH0NCiMgd2lkZ2V0VG9QbmcoDQojICAgY29sbGFwc2libGVUcmVlU3VtbWFyeSgNCiMgICBhbW91bnRfYWNjb3VudF9kYXRhLA0KIyAgIGhpZXJhcmNoeSA9IGMoInoxIiwgIkdyb3VwLjEiLCAieiIsICd4JyksDQojICAgd2lkdGggPSAxMTAwLA0KIyAgIGhlaWdodD0xNDAwLA0KIyAgIGNvbGxhcHNlZCA9IEZBTFNFLA0KIyAgIG1heFBlcmNlbnQgPSA1MCwNCiMgICByb290ID0gIkN1c3RvbWVyIERldGFpbHMiLA0KIyAgIHpvb21hYmxlID0gRkFMU0UNCiMgKSwNCiMgICAiQ3VzdG9tZXJEZXRhaWxzVHJlZS5wbmciDQojICkNCmMgPC0gY29sbGFwc2libGVUcmVlKA0KICBhbW91bnRfYWNjb3VudF9kYXRhLA0KICBoaWVyYXJjaHkgPSBjKCJ6MSIsICJHcm91cC4xIiwgInoiLCAneCcpLA0KICBmaWxsPSJsaWdodHN0ZWVsYmx1ZSIsDQogIHJvb3QgPSAiQ3VzdG9tZXIgRGV0YWlscyIsDQogIHdpZHRoID0gMTEwMCwNCiAgaGVpZ2h0PTE0MDAsDQogIHpvb21hYmxlID0gRkFMU0UsDQogIGNvbGxhcHNlZCA9IFRSVUUsDQopDQpodG1sdG9vbHM6OnNhdmVfaHRtbChjLCBmaWxlPSdDdXN0b21lckRldGFpbHNUcmVlLmh0bWwnKQ0KDQpgYGANCg0KYGBge3J9DQoNCg0KDQpgYGANCg0K